<?php
/**
 * ErrorHook
 * 
 * @author Alexey Strelnikoff <zog@zoggi.net>
 */

namespace Zoggi\ErrorHook;

/**
 * Класс следит за ошибками и передаёт каждую пойманную ошибку в ErrorCatcher
 * 
 * Пример использования:
 * <code>
 * // отключаем обычный показ ошибок
 * ini_set('display_error',false);
 * error_reporting(0);
 * // создаём листенер ошибок PHP
 * $errorListener = new ErrorHook\Listener();
 * // добавляем нотификатор, печатающий в поток вывода (на экран)
 * $errorListener->addNotifier( new ErrorHook\PrintNotifier( E_ALL ) );
 * // добавляем нотификатор, записывающий все ошибки в файл. размер файла буде не более 2mb 
 * $errorListener->addNotifier( new ErrorHook\LogNotifier( E_ALL, '/home/sitedir/error.log', 2) );
 * // добавляем нотификатор, отправляющий все ошибки на емайл
 * $errorListener->addNotifier( new ErrorHook\MailNotifier( E_ALL, 'admin@exmaple.com' ) );
 * </code>
 */
class Listener {

	/**
	 * Ловец ошибок
	 * @var ErrorCatcher 
	 */
	private $catcher;
	private $oldErrorHanlder = null;

	/**
	 * Возвращает объект, который следит за всеми ошибками произошедшими в PHP
	 * 
	 * Метод перенаправляет все возникшие ошибки на $this->catcher->errorHandler.
	 * Кроме этого, метод регистрирует shutdown функцию $this->catcher->shutdownFunction, 
	 * выполняемую в конце скрипта.
	 * 
	 * @use set_error_handler()
	 * @use register_shutdown_function()
	 */
	public function __construct() {

		$this->catcher = new ErrorCatcher();

		// навешиваем свою функцию обработчика ошибок
		$this->oldErrorHanlder = set_error_handler(array($this->catcher, 'errorHandler'));

		// навешиваем свою функцию, которая отработает по завершению программы
		register_shutdown_function(array($this->catcher, 'shutdownFunction'));
	}

	/**
	 * Добавляет нотификатор ошибок
	 * 
	 * @param NotifierInterface $notifier Нотификатор ошибки
	 */
	public function addNotifier( NotifierInterface $notifier ) {

		$this->catcher->addNotifier($notifier);
	}

	/**
	 * Устанавливает обработчик выполняемый, когда произошла ошибка
	 * E_FATAL Allowed memory size of ...
	 * 
	 * @see ErrorCatcher::setMemoryOutCallback()
	 * 
	 * @param Closure $callbackFunction
	 */
	public function setMemoryOutCallback( $callbackFunction ) {
		$this->catcher->setMemoryOutCallback($callbackFunction);
	}

	/**
	 * Отключает все обработчики, и возвращает error_handler в положение "как было"
	 */
	public function __destruct() {
		$this->catcher->disable();
		restore_error_handler();
	}

}